import java.io.*;

public class Experiment2 {

    public static void main(String[] args) throws IOException {
        // 获取3阶幻方对应的置换
        int[] key = getMagicTrans(createMagicSquare(3));

        // 读取本地txt文件中转置加密的明文，进行转置加密
        File transFile = new File("./transposition.txt");
        transposition(transFile, key);

        // 读取本地txt文件幻方加密的明文，进行幻方加密
        File magicFile = new File("./magic_square.txt");
        magicSquare(magicFile, key);
    }

    // 置换加密
    public static void transposition(File transFile, int[] key) throws IOException {
        String[] plainText = readTxt(transFile);
        System.out.println("\n\n置换加密的明文: ");
        for (int i = 0; i < plainText.length; i++) {
            System.out.print(plainText[i] + " ");
        }
        // 将加密后的密文保存到.txt文件中，并以空格隔开
        FileWriter writer = new FileWriter(new File("./trans.txt"));
        System.out.println("\n置换加密的密文: ");
        for (int i = 0; i < key.length; i++) {
            System.out.print(plainText[key[i] - 1] + " ");
            if (i == key.length - 1) {
                writer.write(plainText[key[i] - 1]);
            } else {
                writer.write(plainText[key[i] - 1] + " ");
            }
        }
        // 释放资源
        writer.close();
    }

    // 幻方加密
    private static void magicSquare(File magicFile, int[] key) throws IOException {
        // 获取明文字符串数组
        String[] plainText = readTxt(magicFile);
        System.out.println("\n\n幻方加密的明文: ");
        for (int i = 0; i < plainText.length; i++) {
            System.out.print(plainText[i] + " ");
        }
        // 将加密后的密文保存到.txt文件中
        FileWriter writer = new FileWriter(new File("./Magic.txt"));
        // 对明文进行加密，并保存到strArr字符数组中
        String[] strArr = new String[plainText.length];
        for (int i = 0; i < key.length; i++) {
            strArr[key[i] - 1] = plainText[i];
        }
        System.out.println("\n幻方加密的密文: ");
        for (int i = 0; i < key.length; i++) {
            System.out.print(strArr[i] + " ");
            if (i == key.length - 1) { // 字符间以空格隔开，末尾不能留有空格
                writer.write(strArr[i]);
            } else {
                writer.write(strArr[i] + " ");
            }
        }
        System.out.println("");
        // 释放资源
        writer.close();
    }

    // 生成奇数阶幻方，可以是3、5、7、... 、2n+1阶
    public static int[][] createMagicSquare(int k) {
        int[][] magicArr = new int[k][k];
        int x = 0;
        int y = k / 2;
        int total = k * k;
        for (int i = 1; i <= total; i++) {
            magicArr[x][y] = i;
            int m = (x - 1 + k) % k;
            int n = (y + 1) % k;
            if (magicArr[m][n] > 0) {
                x = (x + 1) % k;
            } else {
                x = m;
                y = n;
            }
        }
        System.out.println("生成的3阶幻方：");
        for (int i = 0; i < magicArr.length; i++) {
            for (int j = 0; j < magicArr.length; j++) {
                System.out.print(magicArr[i][j] + " ");
            }
            System.out.println("");
        }
        return magicArr;
    }

    // 幻方对应的置换
    public static int[] getMagicTrans(int[][] arr) {
        int[] res = new int[(int) Math.pow(arr.length, 2)];
        int index = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                res[index++] = arr[i][j];
            }
        }
        System.out.println("\n密钥：");
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i] + " ");
        }
        return res;
    }

    // 读取.txt文件中的明文
    public static String[] readTxt(File file) throws IOException {
        // 通过字符流读取.txt
        BufferedReader br = new BufferedReader(new FileReader(file));
        // 将读取到的明文以空格进行分割，并保存到字符串数组中
        String[] plainText = br.readLine().split(" ");
        // 释放资源
        br.close();
        return plainText;
    }
}
